﻿using EntityframeworkDemo.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Linq.Expressions;

namespace EntityframeworkDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            AddData();
            //UpdateData();
            SearchData();
            Console.ReadLine();
        }

        public static async void AddData()
        {
            //ILoggerFactory MyLoggerFactory
            //           = LoggerFactory.Create(builder => { builder.AddConsole(); });
            //var options = new DbContextOptionsBuilder<DemoDbContext>()
            //         .UseInMemoryDatabase(databaseName: "Add_writes_to_database")
            //        .UseLoggerFactory(MyLoggerFactory)
            //       .Options;

            using (var context = new DemoDbContext())
            {
                var data = new User { Name = "zhangsan", RealName = "张三", EmailAddress = "123234324@qq.com", CreateOn = new DateTime(2020, 1, 1) };

                var organization = new Organization() { Name = "河北" };
                data.Organization = organization;
                //if (await context.Users.AnyAsync(x => x.Id == 1))
                //{
                //    data.Id = 1;
                //    var entity = context.Attach(data);
                //}
                //else
                //{
                    context.Users.Add(data);
                //}

                context.SaveChanges();

                var user = await context.Users.FirstOrDefaultAsync(x => x.Id == 1);
                Console.WriteLine($"Id: {user.Id}");
                Console.WriteLine($"Name: {user.Name}");
                Console.WriteLine($"RealName: {user.RealName}");
                Console.WriteLine($"EmailAddress: {user.EmailAddress}");
                Console.WriteLine($"CreateOn: {user.CreateOn}");
                Console.WriteLine($"CreateOn: {user.Organization.Name}");
                Console.WriteLine("添加用户完毕");
                Console.WriteLine("-------------------");
            }
        }

        public static async void UpdateData()
        {
            //var options = new DbContextOptionsBuilder<DemoDbContext>()
            //  .UseInMemoryDatabase(databaseName: "Add_writes_to_database")
            //  .Options;
            var user = new User { Id = 1, Name = "zhangsan", RealName = "张三", EmailAddress = "535133951@qq.com" };
            using (var context = new DemoDbContext())
            {
                Console.WriteLine($"the entity statte before attach: {context.Entry(user).State}");
                var entity = context.Attach(user);
                Console.WriteLine($"the entity statte after attach: {context.Entry(user).State}");
                user.RealName = "李四";
                Console.WriteLine($"the entity statte after chagned: {context.Entry(user).State}");
                entity.Property(x => x.EmailAddress).IsModified = true;
                context.SaveChanges();
                Console.WriteLine($"the entity statte after savechange: {context.Entry(user).State}");

            }

            using (var context = new DemoDbContext())
            {

                var user2 = await context.Users.FirstOrDefaultAsync(x => x.Id == 1);
                Console.WriteLine($"the entity statte after firstOrDefault: {context.Entry(user2).State}");
                Console.WriteLine($"Id: {user2.Id}");
                Console.WriteLine($"Name: {user2.Name}");
                Console.WriteLine($"RealName: {user2.RealName}");
                Console.WriteLine($"EmailAddress: {user2.EmailAddress}");
                Console.WriteLine("-------------------");
            }
        }

        public static async void SearchData()
        {
            using (var context = new DemoDbContext())
            {
                var range = new TimeRange(new DateTime(2019, 1, 1), DateTime.Now);
                //var user = await context.Users.FirstOrDefaultAsync();
                var user = await context.Users.Where(x =>
                 range.StartTime.HasValue ? range.StartTime <= x.CreateOn.AddDays(x.Id) : true
                 && range.EndTime.HasValue ? x.CreateOn <= range.EndTime : true
            ).FirstOrDefaultAsync();

                Console.WriteLine($"the entity statte after firstOrDefault: {context.Entry(user).State}");
                Console.WriteLine($"Id: {user.Id}");
                Console.WriteLine($"Name: {user.Name}");
                Console.WriteLine($"RealName: {user.RealName}");
                Console.WriteLine($"EmailAddress: {user.EmailAddress}");
                Console.WriteLine($"EmailAddress: {user.CreateOn}");
                Console.WriteLine("-------------------");
            }
        }

        static bool InTimeRange(TimeRange range, DateTime time)
        {
            if (range != null)
            {
                return range.StartTime.HasValue ? range.StartTime <= time : true
                    && range.EndTime.HasValue ? time <= range.EndTime : true;
            }
            return true;
        }
    }
}
